﻿using System;
using System.Web;
using HtmlAgilityPack;
using System.Drawing;
using System.Diagnostics;
using System.Net;
using System.IO;


// ReSharper disable CheckNamespace
namespace Yah.Parser
// ReSharper restore CheckNamespace
{
    /// <summary>
    ///Các hàm phục vụ cho việc lấy kích thược của thẻ img 
    ///GetSizeOfImgNode là hàm chính
    /// </summary>
    public class ImageProcess
    {
        private readonly HtmlDocument _htmlDocument;
        private readonly string _url;

        public ImageProcess(string url, HtmlDocument htmdoc)
        {
            _url = url;
            _htmlDocument = htmdoc;
        }

        /// <summary>
        /// Các thuôc tính width thường có thêm đơn vị ở đăng sau, hàm này quy đổi về pixel và tra về số nguyên
        /// Nếu giá trị thuộc tính sai, hoặc là thộc tính ở dạng % thì sẽ trả về -1
        /// </summary>
        /// <param name="attributeValue"></param>
        /// <returns></returns>
        private static int _getNumberFormWHAttribute(string attributeValue)
        {
            attributeValue = attributeValue.Trim();
            if (attributeValue == "")
            {
                return -1;
            }
            string num = "";
            string c = ""; //pt px em//12 16 1  bảng quy đổi http://reeddesign.co.uk/test/points-pixels.html
            foreach (char t in attributeValue)
            {
                if (t < '0' || '9' < t)
                {
                    c += t;
                }
                else
                {
                    num += t;
                }
            }
            int intNum;
            try
            {
                intNum = Convert.ToInt32(num);
            }
            catch (Exception)
            { 
                throw new Exception(@"Không convert duoc num ="+num);
            }
            if (c == "pt")
            {
                intNum = intNum/12*16;
            }
            else if (c == "em")
            {
                intNum *= 16;
            }
            else if (c == "%")
            {
                intNum = -1;
            }
            return intNum;
        }

        /// <summary>
        /// Đưa vào thẻ img lấy ra size của ảnh đó, bằng cách đọc thuộc tính của thẻ img, nếu không có thuộc tính này thì sẽ đọc header của file ảnh 
        /// </summary>
        /// <param name="inp"></param>
        /// <returns></returns>
        public Size GetSizeOfImgNode(HtmlNode inp)
        {
            //<img width="480" height="320" border="1" alt="Ảnh" src="/Files/Subject/3b/bd/c8/75/anh_1_480.jpg">
            int heightAttri = -1;
            int widthAttri = -1;
            if (inp.Attributes["height"] != null)
            {
                //đọc lấy giá trị dạng số của thuộc tính height
                heightAttri = _getNumberFormWHAttribute(inp.Attributes["height"].Value);
            }
            if (inp.Attributes["width"] != null)
            {
                //đọc lấy giá trị dạng số của thuộc tính height
                widthAttri = _getNumberFormWHAttribute(inp.Attributes["width"].Value);
            }
            //Nếu chiều rộng hoặc chiều cao chưa được xét thì phải đọc header của anh để lấy kích thược ảnh
            if (heightAttri == -1 || widthAttri == -1)
            {
                var imgSize = new Size();
                try
                {
                    imgSize = _imgSizeFormUrl(GetUrlFormSrc(inp.Attributes["src"].Value));
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("GetSizeOfImgNode: " + ex.Message);
                }
                finally
                {
                    //lấy được kích thược ảnh, tính tỉ lệ để đưa ra kích thược thực tế của ảnh;
                    if (heightAttri == -1 && widthAttri == -1)
                    {
                        heightAttri = imgSize.Height;
                        widthAttri = imgSize.Width;
                    }
                    else if (heightAttri == -1)
                    {
                        heightAttri = (int) ((imgSize.Height/(float) imgSize.Width)*widthAttri);
                    }
                    else if (widthAttri == -1)
                    {
                        widthAttri = (int) (((float) imgSize.Width/imgSize.Height)*heightAttri);
                    }
                }
            }
            //Kiếm tra các thuộc tính và trả về kết quả
            if (heightAttri == -1 || widthAttri == -1)
            {
                return new Size(0, 0);
            }
            return new Size(widthAttri, heightAttri);
        }

        /// <summary>
        /// Địa chỉ base của trang web phục vụ cho việc load ảnh, địa chỉ này được lòa lần đầu khi chạy hàm _getUrlFormSrc
        /// Địa chỉ có chứa sẵn đấu / ở cuối
        /// </summary>
        private string _baseUrl;

        /// <summary>
        /// Đưa vào thuộc tính src trả về full url của ảnh
        /// Trong xử lý này còn thiếu phần trong url có dạng ../../
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public string GetUrlFormSrc(string src)
        {
            if (String.IsNullOrEmpty(src)) return "";
            //base url là đường dẫn đến thư mục hiện hành của web, dường dẫn này được lấy từ địa chỉ url hoặc là trong thẻ base đầu tiên nằm trong head
            //thẻ base được ưu tiên hơn là url
            if (_baseUrl == null)
            {
                try
                {
                    HtmlNode baseNode =
                        _htmlDocument.DocumentNode.ChildNodes["html"].ChildNodes["head"].ChildNodes["base"];
                    if (baseNode != null)
                    {
                        _baseUrl = baseNode.Attributes["href"].Value;
                    }
                }
                catch
                {
                    _baseUrl = null;
                }
                if (_baseUrl == null)
                {
                    _baseUrl = _url;
                }
            }
            src = HttpUtility.HtmlDecode(src);
            var srcUri = new Uri(new Uri(_baseUrl), src);
            src = srcUri.AbsoluteUri;

            Debug.WriteLine("_getUrlFormSrc: " + src);
            return src;
        }

        private Size _imgSizeFormUrl(string url)
        {
            var imageRequest = (HttpWebRequest) WebRequest.Create(url);
            var imageResponse = imageRequest.GetResponse();

            var responseStream = imageResponse.GetResponseStream();

            Debug.Assert(responseStream != null, "responseStream != null");
            using (var br = new BinaryReader(responseStream))
            {
                return DevWilson.ImageHeader.GetDimensions(br);
            }
        }
    }
}